/*
===========================================================================
This source file is part of DyLab (Dynamic Laboratory)
For the latest info, see http://dylab.googlecode.com

Copyright (c) 2006-2008 Lukas Krejci
(krejci.lukas@volny.cz)

This file is part of DyLab.

    DyLab is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    DyLab is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with DyLab.  If not, see <http://www.gnu.org/licenses/>.
===========================================================================
*/

#ifndef __dylab_Face_h__
#define __dylab_Face_h__

//===========================================================================================
#include <dylab/simobject/boundarymesh/Vertex.h>
#include <dylab/utils/geometry/TriangleGeometry3.h>
#include <dylab/utils/containers/HashObjContainer.h>

//===========================================================================================
namespace dylab {

    /** This class represents a boundary mesh face.
	*/
    class DYLAB_EXPORT Face
    {
    public:
        typedef uint32_t id_t;

    protected:                
        Vertex * mVertices[TriangleGeometry3::V_COUNT];                
        Vector3  mNormal;

    private:
        /// Non-initialized construction is not allowed.
        Face();
    public:                
        Face(Vertex * _v0, Vertex * _v1, Vertex * _v2, const Vector3 & _normal = Vector3::ZERO);
        Face(Vertex * (&_vertices)[TriangleGeometry3::V_COUNT], const Vector3 & _normal = Vector3::ZERO);
        
        Vertex * vertex(TriangleGeometry3::vertexidx_t _vertexIdx)
                { return mVertices[_vertexIdx]; }                
        const Vertex * vertex(TriangleGeometry3::vertexidx_t _vertexIdx) const
                { return mVertices[_vertexIdx]; } 
        
        Vector3 & normal()
                { return mNormal; }                
        const Vector3 & normal() const
                { return mNormal; }
        
        uint32_t getVertexIndex(TriangleGeometry3::vertexidx_t _vertexIdx) const
                { return mVertices[_vertexIdx]->getIndex(); }                

        TriangleGeometry3 getGeometry() const
                { return TriangleGeometry3(mVertices[TriangleGeometry3::V_0]->position(), 
					mVertices[TriangleGeometry3::V_1]->position(), 
					mVertices[TriangleGeometry3::V_2]->position()); } 

        void updateNormal()
                { mNormal = getGeometry().computeNormal(); }        

        void distributeNormal();
    };
    //-----------------------------------------------------------------------------

	//===========================================================================================
    class DYLAB_EXPORT FaceContainer
        : public HashObjContainer<Face::id_t, Face>
    {
    public:
        FaceContainer(bool _objectOwner)
            : HashObjContainer<Face::id_t, Face>(_objectOwner)
                { }
    };
    //-----------------------------------------------------------------------------

}
//===========================================================================================
#endif // __dylab_Face_h__
